package com.example.demo.redis;

import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.RandomUtil;

import java.util.concurrent.CountDownLatch;

/**
 * 减库存线程
 */
public class StockThread extends Thread {

    /**
     * 库存服务
     */
    private StockService stockService;

    /**
     * 开始倒计时
     */
    private CountDownLatch startLatch;

    /**
     * 结束倒计时
     */
    private CountDownLatch endLatch;

    public StockThread(StockService stockService, CountDownLatch startLatch, CountDownLatch endLatch) {
        this.stockService = stockService;
        this.startLatch = startLatch;
        this.endLatch = endLatch;
    }

    @Override
    public void run() {
        try {
            startLatch.await();
            //这里使用注释切换不同的减库存方法进行测试
//            this.subStock();
            this.safeSubStock();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            endLatch.countDown();
        }
    }

    /**
     * 不安全的减库存方法
     */
    private void subStock() {
        stockService.subStock();
    }

    /**
     * 并发安全的减库存方法
     */
    private void safeSubStock() {
        while (true) {
            //一直减库存直到成功，失败则等待随机时间
            try {
                stockService.safeSubStock();
                return;
            } catch (RedisLockException e) {
                System.out.println(Thread.currentThread().getName() + " " + e.getMessage());
                ThreadUtil.sleep(RandomUtil.randomInt(1000));
            }
        }
    }

}